﻿using Microsoft.Extensions.Configuration;
using Serilog;
using Spectre.Console;
using System.Diagnostics;
using WorkTool.Helpers;

namespace WorkTool
{
    public class Base64ToFile : ITools
    {
        public void ToolsMethod(IConfigurationRoot config)
        {
            string base64String;
            while (true)
            {
                var base64Line = AnsiConsole.Ask<string>("[bold][green1]请输入Base64文件地址（输入 n 取消）：[/] [/]");
                if (base64Line.ToLower().Trim() == "n")
                    return;
                if (File.Exists(base64Line))
                {
                    base64String = File.ReadAllText(base64Line);
                    if (string.IsNullOrEmpty(base64Line))
                    {
                        AnsiConsole.MarkupLine("[yellow]Base64文件无内容，请重新输入！[/]");
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    AnsiConsole.MarkupLine("[yellow]Base64文件地址不存在，请重新输入！[/]");
                }
            }
            string fileType = FileTypeDetector.GetFileTypeFromBase64(base64String);
            if (fileType.Equals("unknown"))
            {
                fileType = FileTypeDetector.GetFileTypeFromBase64(base64String);
            }
            string extension = FileTypeDetector.GetFileExtensionFromMimeType(fileType);
            var filePath = Path.Combine(SettingsHelper._fileSettings.SaveFolder, $"Base64-{DateTime.Now:yyyyMMddHHmmss}{extension}");
            byte[] fileBytes = Convert.FromBase64String(base64String);
            File.WriteAllBytes(filePath, fileBytes);
            AnsiConsole.MarkupLine($"[green1]文件已保存至\n[/] [bold][aqua]{filePath}[/][/]");
            Process.Start(new ProcessStartInfo
            {
                FileName = filePath,
                UseShellExecute = true
            });
            AnsiConsole.MarkupLine("[grey]按任意键继续...[/]");
            Console.ReadKey();
        }
    }

    public static class FileTypeDetector
    {
        private static readonly Dictionary<string, string> MimeTypes = new Dictionary<string, string>
        {
            { "FFD8FF", "image/jpeg" },
            { "89504E47", "image/png" },
            { "47494638", "image/gif" },
            { "25504446", "application/pdf" },
            { "504B0304", "application/zip" },
            { "52617221", "application/x-rar-compressed" },
            { "494433", "audio/mpeg" },
            { "57415645", "audio/wav" },
            { "41564920", "video/x-msvideo" },
            { "000001BA", "video/mpeg" },
            { "000001B3", "video/mpeg" }
        };

        public static string GetFileTypeFromBase64(string base64String)
        {
            if (string.IsNullOrEmpty(base64String))
                return "unknown";

            try
            {
                // 处理可能包含MIME前缀的Base64字符串
                string cleanBase64 = base64String;
                if (base64String.Contains("data:") && base64String.Contains(";base64,"))
                {
                    var parts = base64String.Split(',');
                    if (parts.Length > 1)
                        cleanBase64 = parts[1];
                }

                byte[] data = Convert.FromBase64String(cleanBase64);
                return GetFileTypeFromBytes(data);
            }
            catch (Exception ex)
            {
                Log.Error(ex, ex.Message);
                return "unknown";
            }
        }

        public static string GetFileTypeFromBytes(byte[] bytes)
        {
            if (bytes == null || bytes.Length == 0)
                return "unknown";

            // 将前几个字节转换为十六进制字符串
            string hexSignature = BitConverter.ToString(bytes.Take(8).ToArray())
                .Replace("-", "")
                .ToUpper();

            // 检查已知的文件签名
            foreach (var signature in MimeTypes.Keys)
            {
                if (hexSignature.StartsWith(signature))
                    return MimeTypes[signature];
            }

            return "unknown";
        }

        public static string GetFileExtensionFromMimeType(string mimeType)
        {
            var mimeToExtension = new Dictionary<string, string>
            {
                { "image/jpeg", ".jpg" },
                { "image/png", ".png" },
                { "image/gif", ".gif" },
                { "application/pdf", ".pdf" },
                { "application/zip", ".zip" },
                { "application/x-rar-compressed", ".rar" },
                { "audio/mpeg", ".mp3" },
                { "audio/wav", ".wav" },
                { "video/x-msvideo", ".avi" },
                { "video/mpeg", ".mpeg" }
            };

            return mimeToExtension.TryGetValue(mimeType, out var extension) ? extension : ".bin";
        }
    }
}